package com.yuntoyun.fwcore.util;
/*
 * +----------------------------------------------------------------------
 * | @Author: codeavatar   @Year：2021
 * +----------------------------------------------------------------------
 * | @Email: codeavatar@aliyun.com
 * +----------------------------------------------------------------------
 */
import android.content.Context;
import android.content.SharedPreferences;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonToken;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
import java.util.Set;

/**
 * 内部存储工具类
 */
public class FwSharedPreferencesUtil {

    private static FwSharedPreferencesUtil init = null;

    public static FwSharedPreferencesUtil builder() {
        if (null == init) {
            init = new FwSharedPreferencesUtil();
        }
        return init;
    }

    //////////////////////////////////////////////////////////////
    //+++//常用简化方法 开始
    //////////////////////////////////////////////////////////////


    /**
     * 保存字符串
     *
     * @param key
     * @param value
     * @param filename
     * @return
     */
    public boolean setString(String key, String value, String filename) {
        return setSharedPreferencesData(key, value, DataType.STRING, filename);
    }

    /**
     * 读取字符串
     *
     * @param key
     * @param filename
     * @return
     */
    public String getString(String key, String filename) {
        return (String) getSharedPreferencesData(key, DataType.STRING, filename);
    }


    /**
     * 保存整数
     *
     * @param key
     * @param value
     * @param filename
     * @return
     */
    public boolean setInt(String key, int value, String filename) {
        return setSharedPreferencesData(key, value, DataType.INT, filename);
    }

    /**
     * 读取整数
     *
     * @param key
     * @param filename
     * @return
     */
    public int getInt(String key, String filename) {
        return (int) getSharedPreferencesData(key, DataType.INT, filename);
    }

    /**
     * 保存布尔值
     *
     * @param key
     * @param value
     * @param filename
     * @return
     */
    public boolean setBoolean(String key, boolean value, String filename) {
        return setSharedPreferencesData(key, value, DataType.BOOLEAN, filename);
    }

    /**
     * 读取布尔值
     *
     * @param key
     * @param filename
     * @return
     */
    public boolean getBoolean(String key, String filename) {
        return (boolean) getSharedPreferencesData(key, DataType.BOOLEAN, filename);
    }


    /**
     * 保存浮点型值
     *
     * @param key
     * @param value
     * @param filename
     * @return
     */
    public boolean setFloat(String key, float value, String filename) {
        return setSharedPreferencesData(key, value, DataType.FLOAT, filename);
    }

    /**
     * 读取浮点型值
     *
     * @param key
     * @param filename
     * @return
     */
    public float getFloat(String key, String filename) {
        return (float) getSharedPreferencesData(key, DataType.FLOAT, filename);
    }


    /**
     * 保存长整型值
     *
     * @param key
     * @param value
     * @param filename
     * @return
     */
    public boolean setLong(String key, long value, String filename) {
        return setSharedPreferencesData(key, value, DataType.LONG, filename);
    }

    /**
     * 读取长整型值
     *
     * @param key
     * @param filename
     * @return
     */
    public long getLong(String key, String filename) {
        return (long) getSharedPreferencesData(key, DataType.LONG, filename);
    }

    /**
     * 保存字符串集合
     *
     * @param key
     * @param value
     * @param filename
     * @return
     */
    public boolean setStringSet(String key, Set<String> value, String filename) {
        return setSharedPreferencesData(key, value, DataType.STRINGSET, filename);
    }

    /**
     * 读取字符串集合
     *
     * @param key
     * @param filename
     * @return
     */
    public Set<String> getStringSet(String key, String filename) {
        return (Set<String>) getSharedPreferencesData(key, DataType.STRINGSET, filename);
    }

    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    //+++//常用简化方法 结束
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


    /**
     * JsonObject形式内置保存数据
     *
     * @param jsonObject
     * @param filename
     * @return
     */
    public boolean setSharedPreferencesData(JsonObject jsonObject, String
            filename) {
        if (null == jsonObject) return false;

        Context context = FwApplicationUtil.appContext();
        SharedPreferences sharedPreferences = context.getSharedPreferences(filename, Context
                .MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        Set<String> set = jsonObject.keySet();
        for (String key : set) {
            JsonElement je = jsonObject.get(key);
            if (je.isJsonObject()) {
                editor.putString(key, je.toString());
            } else if (je.isJsonArray()) {
                editor.putString(key, je.toString());
            } else if (je.isJsonPrimitive()) {
                JsonPrimitive jsonPrimitive = je.getAsJsonPrimitive();
                if (jsonPrimitive.isString()) {
                    editor.putString(key, jsonPrimitive.getAsString());
                } else if (jsonPrimitive.isBoolean()) {
                    editor.putBoolean(key, jsonPrimitive.getAsBoolean());
                } else if (jsonPrimitive.isNumber()) {
                    Number number = jsonPrimitive.getAsNumber();
                    if (number instanceof Integer) {
                        editor.putInt(key, number.intValue());
                    } else if (number instanceof Long) {
                        editor.putLong(key, number.longValue());
                    } else if (number instanceof Float) {
                        editor.putFloat(key, number.floatValue());
                    } else if (number instanceof Double) {
                        editor.putString(key, number.doubleValue() + "");
                    }
                }
            } else if (je.isJsonNull()) {
                editor.putString(key, "");
            }
        }
        //commit是将修改数据原子提交到内存，并且同步提交到硬件磁盘；
        return editor.commit();
    }

    /**
     * Map形式内置保存数据
     *
     * @param map
     * @param filename
     * @return
     */
    public boolean setSharedPreferencesData(Map<String, ?> map, String filename) {
        if (null == map) return false;

        Context context = FwApplicationUtil.appContext();
        SharedPreferences sharedPreferences = context.getSharedPreferences(filename, Context
                .MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        Set<String> set = map.keySet();
        for (String key : set) {
            this.putEditorData(key, map.get(key), editor);
        }
        //commit是将修改数据原子提交到内存，并且同步提交到硬件磁盘；
        return editor.commit();
    }

    /**
     * 单独内置保存数据
     *
     * @param key
     * @param value
     * @param dataType 默认STRING类型
     * @param filename
     */
    public boolean setSharedPreferencesData(String key, Object value, DataType
            dataType, String filename) {
        SharedPreferences sharedPreferences = FwApplicationUtil.appContext().getSharedPreferences
                (filename, Context
                        .MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (DataType.STRING == dataType) {
            editor.putString(key, String.valueOf(value));
        } else if (DataType.INT == dataType) {
            editor.putInt(key, (int) value);
        } else if (DataType.BOOLEAN == dataType) {
            editor.putBoolean(key, (boolean) value);
        } else if (DataType.FLOAT == dataType) {
            editor.putFloat(key, (float) value);
        } else if (DataType.LONG == dataType) {
            editor.putLong(key, (long) value);
        } else if (DataType.STRINGSET == dataType) {
            editor.putStringSet(key, (Set<String>) value);
        } else {
            editor.putString(key, String.valueOf(value));
        }
        //commit是将修改数据原子提交到内存，并且同步提交到硬件磁盘；
        return editor.commit();
    }

    /**
     * 内置保存数据
     *
     * @param key
     * @param value
     * @param dataType 默认STRING类型
     * @param filename
     */
    public void applySharedPreferencesData(String key, Object value, DataType
            dataType, String filename) {
        SharedPreferences sharedPreferences = FwApplicationUtil.appContext().getSharedPreferences
                (filename, Context
                        .MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (DataType.STRING == dataType) {
            editor.putString(key, String.valueOf(value));
        } else if (DataType.INT == dataType) {
            editor.putInt(key, (int) value);
        } else if (DataType.BOOLEAN == dataType) {
            editor.putBoolean(key, (boolean) value);
        } else if (DataType.FLOAT == dataType) {
            editor.putFloat(key, (float) value);
        } else if (DataType.LONG == dataType) {
            editor.putLong(key, (long) value);
        } else if (DataType.STRINGSET == dataType) {
            editor.putStringSet(key, (Set<String>) value);
        } else {
            editor.putString(key, String.valueOf(value));
        }
        //apply是将修改数据原子提交到内存，而后异步真正提交到硬件磁盘；
        editor.apply();
    }

    /**
     * 读取指定键名的数据
     *
     * @param key
     * @param dataType MAP类型获取所有数据
     * @param filename
     * @return
     */
    public final Object getSharedPreferencesData(String key, DataType dataType,
                                                 String filename) {
        SharedPreferences sharedPreferences = FwApplicationUtil.appContext().getSharedPreferences
                (filename, Context.MODE_PRIVATE);
        if (DataType.STRING == dataType) {
            return sharedPreferences.getString(key, "");
        }
        if (DataType.INT == dataType) {
            return sharedPreferences.getInt(key, -1);
        }
        if (DataType.BOOLEAN == dataType) {
            return sharedPreferences.getBoolean(key, false);
        }
        if (DataType.FLOAT == dataType) {
            return sharedPreferences.getFloat(key, -1f);
        }
        if (DataType.LONG == dataType) {
            return sharedPreferences.getLong(key, -1);
        }
        if (DataType.STRINGSET == dataType) {
            return sharedPreferences.getStringSet(key, null);
        }
        if (DataType.MAP == dataType) {
            return sharedPreferences.getAll();
        }
        return null;
    }

    /**
     * 清除指定文件数据
     *
     * @param filename
     */
    public void clearSharedPreferencesData(String filename) {
        SharedPreferences sharedPreferences = FwApplicationUtil.appContext().getSharedPreferences
                (filename, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear().commit();
    }

    /**
     * 清除指定键数据
     *
     * @param key
     * @param filename
     */
    public void clearSharedPreferencesData(String key, String filename) {
        SharedPreferences sharedPreferences = FwApplicationUtil.appContext().getSharedPreferences
                (filename, Context
                        .MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove(key).commit();
    }

    /**
     * 检测是否存在指定键
     *
     * @param key
     * @param filename
     * @return
     */
    public boolean hasSharedPreferencesKey(String key, String filename) {
        SharedPreferences sharedPreferences = FwApplicationUtil.appContext().getSharedPreferences
                (filename, Context
                        .MODE_PRIVATE);
        return sharedPreferences.contains(key);
    }

    /**
     * 转换成字符串
     *
     * @param filename
     * @return
     */
    public String toString(String filename) {
        StringBuilder sb = new StringBuilder();
        Map<String, ?> map = (Map<String, ?>) getSharedPreferencesData("", DataType.MAP, filename);
        for (Map.Entry<String, ?> entry : map.entrySet()) {
            sb.append(entry.getKey())
                    .append(": ")
                    .append(entry.getValue())
                    .append(FwSpanUtil.LINE_SEPARATOR);
        }
        return sb.toString();
    }

    /**
     * 指定数据类型
     */
    public enum DataType {
        INT, LONG, BOOLEAN, STRING, FLOAT, STRINGSET, MAP
    }

    /**
     * 自动识别数据类型组装数据
     *
     * @param key
     * @param value
     * @return
     */
    private void putEditorData(String key, Object value, SharedPreferences
            .Editor editor) {
        if (value instanceof String) {
            editor.putString(key, String.valueOf(value));
        } else if (value instanceof Integer) {
            editor.putInt(key, (int) value);
        } else if (value instanceof Boolean) {
            editor.putBoolean(key, (boolean) value);
        } else if (value instanceof Float) {
            editor.putFloat(key, (float) value);
        } else if (value instanceof Long) {
            editor.putLong(key, (long) value);
        } else if (value instanceof Number) {
            editor.putInt(key, (int) value);
        } else if (value instanceof Set<?>) {
            editor.putStringSet(key, (Set<String>) value);
        } else {
            editor.putString(key, String.valueOf(value));
        }
    }
}
